home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / Net / Dict.php < prev    next >
PHP Script  |  2004-03-24  |  14KB  |  587 lines

  1. <?php
  2.  
  3. // {{{ license 
  4.  
  5. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  6. //
  7. // +----------------------------------------------------------------------+
  8. // | PHP Version 4                                                        |
  9. // +----------------------------------------------------------------------+
  10. // | Copyright (c) 1997-2002 The PHP Group                                |
  11. // +----------------------------------------------------------------------+
  12. // | This source file is subject to version 2.0 of the PHP license,       |
  13. // | that is bundled with this package in the file LICENSE, and is        |
  14. // | available at through the world-wide-web at                           |
  15. // | http://www.php.net/license/2_02.txt.                                 |
  16. // | If you did not receive a copy of the PHP license and are unable to   |
  17. // | obtain it through the world-wide-web, please send a note to          |
  18. // | license@php.net so we can mail you a copy immediately.               |
  19. // +----------------------------------------------------------------------+
  20. // | Authors: Chandrashekhar Bhosle <cnb@php.net>                         |
  21. // +----------------------------------------------------------------------+
  22. //
  23. // $Id: Dict.php,v 1.3 2002/10/06 04:55:33 cnb Exp $
  24.  
  25. // }}}
  26. // {{{ includes
  27. require_once 'PEAR.php';
  28. require_once 'Net/Socket.php';
  29.  
  30. // }}}
  31. // {{{ defines
  32. define('NET_DICT_SERVER', 'dict.org');
  33. define('NET_DICT_PORT',   '2628');
  34. // }}}
  35.  
  36. /**
  37. *
  38. * @author Chandrashekhar Bhosle <cnb@freedomink.org>
  39. * @package Net
  40. */
  41. class Net_Dict {
  42.  
  43.     // {{{ properties
  44.     /**
  45.     * Default DICT server name
  46.     *
  47.     * @var string
  48.     */
  49.     var $server = NET_DICT_SERVER;
  50.  
  51.     /**
  52.     * Default DICT Port
  53.     *
  54.     * @var int
  55.     */
  56.     var $port = NET_DICT_PORT;
  57.  
  58.     /**
  59.     * Socket object
  60.     *
  61.     * @var object
  62.     */
  63.     var $_socket;
  64.  
  65.     /**
  66.     * Server Information
  67.     *
  68.     * @var string
  69.     */
  70.     var $servinfo;
  71.  
  72.     /**
  73.     * if caching is on or off
  74.     *
  75.     * @var boolean
  76.     */
  77.     var $caching = false;
  78.     
  79.     /**
  80.     * PEAR Cache
  81.     *
  82.     * @var object
  83.     */
  84.     var $cache;
  85.  
  86.     // }}}
  87.     // {{{ Constructor
  88.     /**
  89.     * Constructor
  90.     */
  91.     function Net_Dict()
  92.     {
  93.     }
  94.     
  95.     // }}}
  96.     // {{{ define()
  97.     /**
  98.     * Gets definitions for the specified word in the specified database.
  99.     *
  100.     * @param string $word
  101.     * @param string $database
  102.     * 
  103.     * @return mixed Array of definitions if sucessful, else PEAR_Error
  104.     */
  105.     function define($word, $database='*')
  106.     {
  107.         if ($this->caching) {
  108.             
  109.             if ($defines = $this->cache->get($word, 'Net_Dict_Defs')) {
  110.                 return $defines;
  111.             }
  112.         }
  113.     
  114.         if (!is_object($_socket)) {
  115.             $this->connect();
  116.         }
  117.  
  118.         $resp = $this->_sendCmd("DEFINE $database '$word'");
  119.  
  120.         if (PEAR::isError($resp)) {
  121.             return $resp;
  122.         } 
  123.         
  124.         list($num) = explode(' ', $resp['text'], 2);
  125.  
  126.         for ($i = 0; $i < $num; $i++) {
  127.             $resp = $this->_socket->readLine();
  128.  
  129.             preg_match("/(\d{3})\s+?\"(.+)?\"\s+?(\S+)\s+?\"(.+)?\"/", 
  130.                                                     $resp, $matches);
  131.  
  132.             $defines[$i]['response']    = $resp;
  133.             $defines[$i]['word']        = $matches[2];
  134.             $defines[$i]['database']    = $matches[3];
  135.             $defines[$i]['description'] = $matches[4];
  136.  
  137.             $resp = $this->_getMultiline();
  138.  
  139.             $defines[$i]['definition'] = $resp['text'];
  140.         }
  141.  
  142.         $this->readLine(); /* discard status */
  143.  
  144.         if ($this->caching) {
  145.             $this->cache->save($word, $defines, 0, 'Net_Dict_Defs');
  146.         }
  147.  
  148.         return $defines;
  149.     }
  150.  
  151.     // }}}
  152.     // {{{ match()
  153.     /**
  154.     * Searches an index for the dictionary, and reports words
  155.     * which were found using a particular strategy.
  156.     *
  157.     * @param string $word
  158.     * @param string $strategy
  159.     * @param string $database
  160.     *
  161.     * @return mixed Array of matches if successful, else PEAR_Error
  162.     */
  163.     function match($word, $strategy='substring', $database='*')
  164.     {
  165.         $resp = $this->_sendCmd("MATCH $database $strategy '$word'");
  166.  
  167.         if (PEAR::isError($resp)) {
  168.             return $resp;
  169.         }
  170.  
  171.         $resp = $this->_getMultiLine();
  172.         
  173.         $this->readLine(); /* discard status */
  174.  
  175.         preg_match_all("/(\S+)?\s\"(.+?)\"/", $resp['text'], $matches);
  176.  
  177.         for ($i = 0; $i < count($matches[0]); $i++) {
  178.             $matched[$i]['database'] = $matches[1][$i];
  179.             $matched[$i]['word']     = $matches[2][$i];
  180.         }
  181.  
  182.         return $matched;
  183.     }
  184.     
  185.     // }}} 
  186.     // {{{ showDatabases()
  187.     /**
  188.     * Gets list of available databases
  189.     *
  190.     * @return mixed Array of databases if successful, else PEAR_Error
  191.     */
  192.     function showDatabases()
  193.     {
  194.         $resp = $this->_sendCmd('SHOW DB');
  195.     
  196.         if (PEAR::isError($resp)) {
  197.             return $resp;
  198.         } 
  199.     
  200.         $resp = $this->_getMultiLine();
  201.  
  202.         $this->readLine(); /* discard status */
  203.  
  204.         preg_match_all("/(\S+)?\s+?\"(.+?)\"/", $resp['text'], $matches);
  205.     
  206.         for ($i = 0; $i < count($matches[0]); $i++) {
  207.             $databases[$i]['database']    = $matches[1][$i];
  208.             $databases[$i]['description'] = $matches[2][$i];
  209.         }
  210.     
  211.         return $databases;
  212.     }
  213.     
  214.     // }}} 
  215.     // {{{ showStrategies() 
  216.     /**
  217.     * Gets a list of available strategies
  218.     *
  219.     * @return mixed Array of strategies if successful, else PEAR_Error
  220.     */
  221.     function showStrategies()
  222.     {
  223.         $resp = $this->_sendCmd('SHOW STRAT');
  224.  
  225.         if (PEAR::isError($resp)) {
  226.             return $resp;
  227.         }
  228.     
  229.         $resp = $this->_getMultiLine();
  230.  
  231.         $this->readLine(); /* discard status */
  232.  
  233.         preg_match_all("/(\S+)?\s+?\"(.+?)\"/", $resp['text'], $matches);
  234.  
  235.         for ($i = 0; $i < count($matches[0]); $i++) {
  236.             $strategies[$i]['strategy']    = $matches[1][$i];
  237.             $strategies[$i]['description'] = $matches[2][$i];
  238.         }
  239.  
  240.         return $strategies;
  241.     }
  242.     
  243.     // }}}
  244.     // {{{ showInfo()
  245.     /**
  246.     * Gets source, copyright, and licensing information about the
  247.     * specified database.
  248.     *
  249.     * @param string $database
  250.     *
  251.     * @return mixed string if successful, else PEAR_Error
  252.     */
  253.     function showInfo($database)
  254.     {
  255.         return $this->simpleQuery('SHOW INFO ' . $database);
  256.     }
  257.     
  258.     // }}}  
  259.     // {{{ showServer()
  260.     /**
  261.     * Gets local server information written by the local administrator.
  262.     * This could include information about local databases or strategies,
  263.     * or administrative information such as who to contact for access to
  264.     * databases requiring authentication. 
  265.     *
  266.     * @return mixed string if sucessful, else PEAR_Error
  267.     */
  268.     function showServer()
  269.     {
  270.         return $this->simpleQuery('SHOW SERVER');
  271.     }
  272.     
  273.     // }}} 
  274.     // {{{ client()
  275.     /**
  276.     * Allows the client to provide information about itself
  277.     * for possible logging and statistical purposes.  All clients SHOULD
  278.     * send this command after connecting to the server.  All DICT servers
  279.     * MUST implement this command (note, though, that the server doesn't
  280.     * have to do anything with the information provided by the client).
  281.     *
  282.     * @param string $text
  283.     * 
  284.     * @return mixed string if successful, else PEAR_Error
  285.     */
  286.     function client($text='cnb')
  287.     {
  288.         $this->_sendCmd('CLIENT ' . $text);
  289.     }
  290.     
  291.     // }}}
  292.     // {{{ status()
  293.     /**
  294.     * Display some server-specific timing or debugging information.  This
  295.     * information may be useful in debugging or tuning a DICT server.  All
  296.     * DICT servers MUST implement this command (note, though, that the text
  297.     * part of the response is not specified and may be omitted).
  298.     *
  299.     * @return mixed string if successful, else PEAR_Error
  300.     */
  301.     function status()
  302.     {
  303.         $resp = $this->_sendCmd('STATUS');
  304.     
  305.         return $resp['text'];
  306.     }
  307.     
  308.     // }}} 
  309.     // {{{ help()
  310.     /** 
  311.     * Provides a short summary of commands that are understood by this
  312.     * implementation of the DICT server.  The help text will be presented
  313.     * as a textual response, terminated by a single period on a line by
  314.     * itself.  All DICT servers MUST implement this command.
  315.     *
  316.     * @return mixed string on success, else PEAR_Error
  317.     */
  318.     function help()
  319.     {
  320.         return $this->simpleQuery('HELP');
  321.     }
  322.     
  323.     // }}} 
  324.     // {{{ quit()
  325.     /**
  326.     * This command is used by the client to cleanly exit the server.
  327.     * All DICT servers MUST implement this command.
  328.     *
  329.     * @return mixed string on success, else PEAR_Error
  330.     */
  331.     function quit()
  332.     {
  333.             return $this->_sendCmd('QUIT');
  334.     } 
  335.     
  336.     // }}} 
  337.     // {{{ optionMIME()
  338.     /**
  339.     * Requests that all text responses be prefaced by a MIME header
  340.     * [RFC2045] followed by a single blank line (CRLF).
  341.     * 
  342.     * @return mixed
  343.     */
  344.     function optionMIME()
  345.     {
  346.     }
  347.     
  348.     // }}}
  349.     // {{{ auth()
  350.     /**
  351.     * The client can authenticate itself to the server using a username and
  352.     * password.  The authentication-string will be computed as in the APOP
  353.     * protocol discussed in [RFC1939].
  354.     *
  355.     * @param string $user
  356.     * @param string $auth
  357.     *
  358.     * @return mixed
  359.     */
  360.     function auth($user, $auth)
  361.     {
  362.     
  363.     }
  364.     
  365.     // }}}
  366.     // {{{ SASLAuth()
  367.     /**
  368.     * The Simple Authentication and Security Layer (SASL) is currently
  369.     * being developed [RFC2222].  The DICT protocol reserves the SASLAUTH
  370.     * and SASLRESP commands for this method of authentication.
  371.     *
  372.     * @param string $mechanism
  373.     * @param string $initial_response
  374.     *
  375.     * @return mixed
  376.     */
  377.     function SASLAuth($mechanism, $initial_response)
  378.     {
  379.     
  380.     }
  381.     
  382.     // }}}
  383.     // {{{ SASLResp()
  384.     /**
  385.     * The client will send all responses using the SASLRESP command and a
  386.     * BASE64-encoded parameter.
  387.     *
  388.     * @param string $response
  389.     *
  390.     * @return mixed
  391.     */
  392.     function SASLResp($response)
  393.     {
  394.     
  395.     }
  396.     
  397.     // }}}
  398.     // {{{  connect()
  399.     /**
  400.     * Connects to a dict server and sets up a socket
  401.     *
  402.     * @param string  $server
  403.     * @param integer $port
  404.     *
  405.     * @return mixed true on success, else PEAR_Error
  406.     */
  407.     function connect($server='', $port = 0)
  408.     {
  409.         $s = new Net_Socket;
  410.  
  411.         if (empty($server)) 
  412.             $server = $this->server;
  413.  
  414.         if (0 == $port)
  415.             $port   = $this->port;
  416.         
  417.         $err = $s->connect($server, $port);
  418.     
  419.         if (PEAR::isError($err)) {
  420.             return $err;
  421.         }
  422.     
  423.         $banner = $s->readLine(); 
  424.  
  425.         preg_match("/\d{3} (.*) <(.*)> <(.*)>/", $banner, &$reg);
  426.         $this->servinfo["signature"]    = $reg[1];
  427.         $this->servinfo["capabilities"] = explode(".", $reg[2]);
  428.         $this->servinfo["msg-id"]       = $reg[3];
  429.  
  430.         $this->_socket  = $s;
  431.  
  432.         return true;
  433.     }
  434.     
  435.     // }}}
  436.     // {{{ setServer()
  437.     /**
  438.     * Sets the server and port of dict server
  439.     *
  440.     * @param string $server
  441.     * @param int    $port
  442.     */
  443.     function setServer($server, $port = 0)
  444.     {
  445.         $this->server = $server;
  446.  
  447.         if (0 < $port) {
  448.             $this->port = $port;
  449.         }
  450.     }
  451.  
  452.     // }}}
  453.     // {{{ setCache()
  454.     /**
  455.     * Sets caching on or off and provides the cache type and parameters
  456.     *
  457.     * @param boolean $cache
  458.     * @param string  $container
  459.     * @param array   $container_options
  460.     */
  461.     function setCache($flag = false, $container = '', $container_options = '')
  462.     {
  463.         $this->caching = $flag;
  464.  
  465.         if ($this->caching) {
  466.  
  467.             require_once 'Cache.php';
  468.         
  469.             if (is_object($this->cache))
  470.                     unset($this->cache);
  471.  
  472.             $this->cache = new Cache($container, $container_options);
  473.         } 
  474.     }
  475.  
  476.     // }}}
  477.     // {{{ _sendCmd()
  478.     /**
  479.     * Sends a command, checks the reponse, and
  480.     * if good returns the reponse, other wise
  481.     * returns false.
  482.     *
  483.     * @param  $cmd  Command to send (\r\n will be appended)
  484.     *
  485.     * @return mixed First line of response if successful, otherwise false
  486.     */
  487.     function _sendCmd($cmd)
  488.     {
  489.         $result = $this->_socket->writeLine($cmd);
  490.  
  491.         if (PEAR::isError($result) AND $result) {
  492.             return $result;
  493.         }
  494.  
  495.         $data = $this->_socket->readLine();
  496.  
  497.         if (PEAR::isError($data)) {
  498.             return $data;
  499.         }
  500.  
  501.         $resp['code'] = substr($data, 0, 3);
  502.         $resp['text'] = ltrim(substr($data, 3));
  503.  
  504.         if (!Net_Dict::isOK($resp)) {
  505.             return new PEAR_Error( $resp['text'], 
  506.                                     $resp['code']);
  507.         }
  508.  
  509.         return $resp;
  510.     }
  511.  
  512.     // }}} 
  513.     // {{{ _getMultiline()
  514.     /**
  515.     * Reads a multiline reponse and returns the data
  516.     *
  517.     * @return mixed string on success or PEAR_Error
  518.     */
  519.     function _getMultiline()
  520.     {
  521.         $data = '';
  522.         while(($tmp = $this->readLine()) != '.') {
  523.             if (substr($tmp, 0, 2) == '..') {
  524.                 $tmp = substr($tmp, 1);
  525.             }
  526.             $data .= $tmp . "\r\n";
  527.         }
  528.  
  529.         $resp['text']   = substr($data, 0, -2);
  530.  
  531.         return $resp;
  532.     }
  533.  
  534.     // }}} 
  535.     // {{{ _readLine()
  536.     /**
  537.     * Alias to Net_Socket::readLine();
  538.     */
  539.     function readLine()
  540.     {
  541.         return $this->_socket->readLine();
  542.     }
  543.  
  544.     // }}} 
  545.     // {{{ simpleQuery()
  546.     /**
  547.     * Runs a generic dict query
  548.     *
  549.     * @param string $query
  550.     * 
  551.     * @return mixed string on success, else PEAR_Error
  552.     */
  553.     function simpleQuery($query)
  554.     {
  555.         $resp = $this->_sendCmd($query);
  556.  
  557.         if (PEAR::isError($resp)) {
  558.             return $resp;
  559.         }
  560.  
  561.         $resp = $this->_getMultiLine();
  562.  
  563.         $this->readLine(); /* discard status */
  564.  
  565.         return $resp['text'];
  566.     }
  567.  
  568.     // }}}  
  569.     // {{{ isOK()
  570.     /**
  571.     * Checks if a response code is positive
  572.     * 
  573.     * @param array $resp
  574.     *
  575.     * @return boolean
  576.     */
  577.     function isOK($resp)
  578.     {
  579.         $positives = array(1, 2, 3);
  580.  
  581.         return in_array(substr($resp['code'], 0, 1), $positives);
  582.     }
  583.  
  584.     // }}} 
  585.  
  586. } // end class Dict
  587.